package com.itheima.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.common.PageBean;
import com.itheima.dto.ChangePasswordDto;
import com.itheima.dto.EmpDto;
import com.itheima.dto.EmpLoginDto;
import com.itheima.dto.EmpQueryDto;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.EmpExpr;
import com.itheima.service.EmpService;
import com.itheima.utils.JwtUtils;
import com.itheima.vo.EmpItemVo;
import com.itheima.vo.EmpJobVo;
import com.itheima.vo.EmpLoginVo;
import com.itheima.vo.EmpVo;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;


@Service
public class EmpServiceImpl implements EmpService {
    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private EmpExprMapper empExprMapper;
    @Autowired
    private HttpServletRequest request;


    @Override
    public PageBean pageQuery(EmpQueryDto dto) {
        PageHelper.startPage(dto.getPage(), dto.getPageSize());
        Page<EmpVo> page = empMapper.query(dto);
        long total = page.getTotal();
        List<EmpVo> list = page.getResult();
        PageBean pageBean = new PageBean(total, list);
        return pageBean;
    }

    @Override
    @Transactional//开启事务管理
    public void delete(List<Integer> ids) {
        ids.forEach(id -> {
            empMapper.delete(id);
            empExprMapper.deleteByEmpId(id);
        });
    }


    @Override
    @Transactional//开启事务管理
    public void insert(EmpDto dto) {
        Emp emp = new Emp();
        BeanUtils.copyProperties(dto, emp);//将dto中的数据拷贝到emp对象中
        //emp.setPassword("123456");
        emp.setPassword(DigestUtil.bcrypt("123456"));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.insert(emp);
        List<EmpExpr> exprList = dto.getExprList();
        exprList.forEach(empExpr -> {
            empExpr.setEmpId(emp.getId());
            empExprMapper.insert(empExpr);
        });
    }

    @Override
    public EmpVo findById(Integer id) {
        Emp emp = empMapper.findById(id);
        EmpVo empVo = new EmpVo();
        BeanUtils.copyProperties(emp, empVo);
        List<EmpExpr> empExprList = empExprMapper.getByEmpId(id);
        empVo.setExprList(empExprList);
        return empVo;
    }

    @Override
    @Transactional//开启事务管理
    public void update(EmpDto dto) {
        Emp emp = new Emp();
        BeanUtils.copyProperties(dto, emp);
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.update(emp);
        List<EmpExpr> exprList = dto.getExprList();
        empExprMapper.deleteByEmpId(emp.getId());
        exprList.forEach(empExpr -> {
            empExpr.setEmpId(emp.getId());
            empExprMapper.insert(empExpr);
        });
    }

    @Override
    public List<Emp> findAll() {
        return empMapper.findAll();
    }

    @Override
    public List<EmpItemVo> getEmpGenderData() {
        return empMapper.getEmpGenderData();
    }

    @Override
    public EmpJobVo getEmpJobData() {
        List<EmpItemVo> list = empMapper.getEmpJobData();
        /*//第一种方式：集合遍历处理实现
        List<String> list1 = new ArrayList();
        List<Integer> list2 = new ArrayList();
        list.forEach(empItemVo -> {
            String name = empItemVo.getName();
            list1.add(name);
            Integer value = empItemVo.getValue();
            list2.add(value);
        });
        EmpJobVo EmpJobVo = new EmpJobVo();
        EmpJobVo.setJobList(list1);
        EmpJobVo.setDataList(list2);
        return EmpJobVo;*/
        /*//第二种方式：使用stream流实现
        //使用stream流实现
        //遍历 List<EmpItemVo>， 将每个ItemVo的职位名称获取出来，形成一个新的List<String>
        List<String> jobs = list.stream().map(vo -> vo.getName()).collect(Collectors.toList());
        //遍历 List<EmpItemVo>， 将每个ItemVo的职位数量获取出来，形成一个新的List<Integer>
        List<Integer> counts = list.stream().map(vo -> vo.getValue()).collect(Collectors.toList());*/


        //第三种方式：使用Hutool工具包中的
        List<String> jobs = CollUtil.getFieldValues(list, "name", String.class);
        List<Integer> counts = CollUtil.getFieldValues(list, "value", Integer.class);
        return EmpJobVo.builder().jobList(jobs).dataList(counts).build();
    }

    @Override
    //员工登录
    public EmpLoginVo login(EmpLoginDto dto) {
        Emp emp = empMapper.findByUsername(dto.getUsername());
        if (emp == null) {
            throw new RuntimeException("用户名不存在");
        }
        //if (!StrUtil.equals(emp.getPassword(),dto.getPassword())){
        if (!DigestUtil.bcryptCheck(dto.getPassword(), emp.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("id", emp.getId());
        String jwt = JwtUtils.createJwt(map);
        return EmpLoginVo.builder()
                .id(emp.getId())
                .name(emp.getName())
                .username(emp.getUsername())
                .token(jwt) //jwt令牌
                .build();
    }

    @Override
    public void changePassword(ChangePasswordDto dto) {
        String jwt = request.getHeader("token");
        Map<String, Object> map = JwtUtils.parseJwt(jwt);
        String id = map.get("id").toString();
        Emp emp = empMapper.findById(Integer.valueOf(id));
        if (!DigestUtil.bcryptCheck(dto.getPassword(), emp.getPassword())) {
            throw new RuntimeException("原始密码不正确");
        }
        if (!dto.getPassword().equals(dto.getRepassword())) {
            throw new RuntimeException("原始密码和确认原始密码不匹配");
        }
        emp.setPassword(DigestUtil.bcrypt(dto.getNewpassword()));
        empMapper.update(emp);
    }


}
